Introduction
Charlie Reams’ document entitled Apterous Rating System contains a technical outline of how the Apterous rating system is implemented. In particular, it explains how to calculate how much a player’s rating changes after winning or losing a game. This change in rating is known as \(\Delta r\) (“delta-r”), and is positive for a win and negative for a loss. In this document, I provide a graphical representation of how \(\Delta r\) varies based on the ratings of the players in a game, and the margin of victory (or defeat) in the game. There are two master plots which include a very wide range of player ratings and margins of victory and defeat. These are followed by sub plots which zoom in on the master plots and focus on combinations of player ratings and margins of victory that might be encountered more often.
Technical Details
The precise details on how to calculate \(\Delta r\) are contained in Charlie’s document. I provide a summary of them in this section.
Calculating \(\Delta r\)
We calculate the change in rating as \[
\Delta r = bcpl,
\] where:
\(b\) is the base rating change, given by \(b = \alpha + \beta|m|\), where \(m\) is the margin of victory.
\(c\) is the compensation factor for the original ratings difference. This is intended to reward players more for beating players rated above them, and punish them less for losing to such players. It is defined as \[
c = w - \frac{1}{1 + \exp(\gamma(r_{P1} - r_{P2}))},
\] where \(r_{P1}\) are the ratings for players one and two, and \(w\) is defined as \[
w = \begin{cases}1 & \text{for the winner} \\1/2 & \text{for draws} \\ 0 & \text{for the loser}\end{cases}
\]
\(p\) is the provisionality factor. In this document we will only consider fully rated players, in which case \(p = 1\).
\(l\) is is the length factor, which essentially measures how long the game was. Clearly a 15-round game is far more statistically significant than a 1- round conundrum attack, and the rating change reflects this. It is defined as \[
l = \mu \ln(1 + n)
\] where \(n\) is the number of rounds in the game. \(l\) is also capped at \(\lambda\), so that even enormously long games cannot cause huge ratings swings. The value of \(\mu\) in Apterous is set so that \(n = 15\) gives \(l = 1\), so this factor essentially disappears for standard 15-round games.
Constants
The constants used are outlined in the below table:
| \(\alpha\) |
20 |
| \(\beta\) |
1/2 |
| \(\gamma\) |
0.00575 |
| \(\lambda\) |
2 |
| \(\mu\) |
1/ln16 = 0.361… |
| \(\sigma\) |
600 |
| \(\tau\) |
133 |
| \(\omega\) |
11 |
Assumptions
There are a number of assumptions made herein which relate to how the calculations are made:
- All players are assumed to be fully rated (\(p = 1\)); provisionally rated players are not included.
- Only wins and losses are considered, draws are ignored (\(w = 1\) for a win; \(w = 0\) for a loss).
- Only games of 15 rounds are considered (\(n = 15\)). Note that it doesn’t matter if you play other games of more or less than 15 rounds. Rather, the below visualisations of \(\Delta r\) are only valid for a 15 round game. Appendix A shows in detail how \(\Delta r\) would vary depending on the number of rounds played, and provides a multipler value (\(l\)) for different lengths of games (\(l = 1\) for a 15 round game). Note however that the multiplier is capped at \(l = 2\), so that games of 255 rounds or more have the same effect. Games of less than 255 rounds have a multiplier value between 0 and 2. The nature of the multiplier is such that you have to play quite a long game to have a significant effect on the rating. Therefore, the ratings of the players and the margin of victory are more relevant to calculating \(\Delta r\), but details of \(l\) are included for reference. For now though, the only thing to note is that the below plots assume games of 15 rounds.
Plots
All of the below plots are contour plots with the difference between player ratings (\(r_{P2}-r_{P1}\)) on the x-axis, margin of victory or defeat (\(m\)) on the y-axis, and \(\Delta r\) shown on the contour lines. Note that in calculating the difference in player ratings, you must subtract your rating from your opponent’s rating in order for the plot to be valid for you. The difference will be negative if you are the higher rated player and positive if you are the lower rated player. For the margin of victory or defeat the sign does not matter, so \(m\) is always positive. See Appendix B for an example which includes instructions on reading a contour plot.
In all of the plots you are player 1 (P1) and your opponent is player 2 (P2). There are two plots for each scenario, one for P1 winning (P1 Wins), and one for P1 losing (P1 Loses).
Master Plots
These two plots show a very wide range of player ratings and margins of victory and defeat. They are useful for getting a broad overview of how the ratings change, including what happens in extreme scenarios where a lower rated player defeats a higher rated player by a large margin.
P1 Wins

P1 Loses

Sub Plots
Similarly Rated Players
These plots zoom in on both axes and are suitable for players who find themselves playing opponents with a similar rating to their own (\(\pm\) 400 points). In this case the margin of victory (or defeat) is taken to be 50 points or less (the master plot can be used for wider margins).
P1 Wins

P1 Loses

Lower Rated Player (P1) -VS- Higher Rated Player (P2)
These plots are suitable for those who find themselves playing against opponents who are rated well above them. In this scenario, P1 can gain a lot of rating points for a win against a highly rated player, but can’t lose many rating points. The limits on the axes reflect this.
P1 Wins

P1 Loses

Higher Rated Player (P1) -VS- Lower Rated Player (P2)
These plots are suitable for those who find themselves playing against opponents who are rated well below them. In this scenario, P1 can’t gain many rating points for a win against a lower rated player, but can lose a lot of rating points for a loss. The limits on the axes reflect this.
P1 Wins

P1 Loses

Appendix A - Effect of No. of Rounds Played
The below plot provides a multipler value (\(l\)) for different lengths of games. If you play longer or shorter games you can find a multiplier for that number of rounds (\(n\)), and multiply it by the value of \(\Delta r\) found in one of the above plots to find how the rating changes for a game of that length. For example, if you play a game of 63 rounds, you multiply \(\Delta r\) by 1.5 to find how much your rating changes. The multiplier is capped at \(l = 2\), so that games of 255 rounds or more have the same effect. Games of less than 255 rounds have a multiplier value between 0 and 2. The nature of the multiplier is such that you have to play quite a long game to have a significant effect on the rating. Several ‘nice’ or ‘even’ values of \(n\) and \(l\) have been indicated on the plot.

Appendix B - Examples
These two examples show how to find \(\Delta r\) in the case of a win. For a loss, proceed in a similar manner, except use one of the plots titled ‘P1 Loses’.
Example 1
Player 1 has a rating of 1,000 points (\(r_{P1} = 1,000\)) while player 2 has a rating of 1,100 points (\(r_{P2} = 1,100\)). The difference in ratings is 100 points (\(r_{P2} - r_{P1} = 100\)). Player 1 wins the game by 10 points (\(m = 10\)). On a plot for P1 Wins, draw a line up from the 100 mark on the x-axis, and a line across from 10 on the y-axis. This is shown in the orange arrows on the plot below. Conveniently, the intersection of these lines lands right on the \(\Delta r\) contour line whose value is 16. Therefore player 1 gains 16 points after this game.
Example 2
Often the numbers aren’t so nice and we have to do so-called interpolating to find our value of \(\Delta r\). This example illustrates that process. Player 1 has a rating of 800 points (\(r_{P1} = 800\)) while player 2 has a rating of 1,077 points (\(r_{P2} = 1,077\)). The difference in ratings is 277 points (\(r_{P2} - r_{P1} = 277\)). Player 1 wins the game by 25 points (\(m = 25\)). These numbers aren’t marked on the axes, so we instead interpolate to find the value. This is essentially guessing with our eye where the value appears on the axis. Draw a line up from about halfway between the 250 and 300 marks on the x-axis (for \(r_{P2} - r_{P1} = 277\)), and a line across from halfway between 20 and 30 on the y-axis (for \(m = 25\)). This is shown in the purple arrows on the plot below. Unfortunately, the intersection of these lines doesn’t land right on a \(\Delta r\) contour line. Instead we must interpolate to find the value of \(\Delta r\). The intersection point is about halfway between the contour lines with values of 26 and 28. Therefore we can estimate a value for \(\Delta r\) of 27 in this case.

LS0tCnRpdGxlOiAiPGI+QXB0ZXJvdXMgUmF0aW5nIFN5c3RlbSBWaXN1YWxpemVkPC9iPiIKYXV0aG9yOiAiPGk+QnJpYW4gSGFzc2V0dDwvaT4iCmRhdGU6ICI8aT5TZXB0ZW1iZXIgMjAxOTwvaT4iCm91dHB1dDogCiAgaHRtbF9ub3RlYm9vazogCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgdGhlbWU6IGNlcnVsZWFuCiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiAxCi0tLQoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KIyMjIFByZWxpbXMgIyMjCgojIExpYnJhcmllcwpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShyZXNoYXBlKQpsaWJyYXJ5KGRpcmVjdGxhYmVscykKbGlicmFyeShsYXRleDJleHApCgojIENvbnN0YW50cwphbHBoYSA8LSAyMApiZXRhIDwtIDAuNQpnYW1tYSA8LSAwLjAwNTc1Cm11IDwtIDEgLyBsb2coMTYpCmxhbWJkYSA8LSAyCmBgYAoKIyBJbnRyb2R1Y3Rpb24KCkNoYXJsaWUgUmVhbXMnIGRvY3VtZW50IGVudGl0bGVkIF9BcHRlcm91cyBSYXRpbmcgU3lzdGVtW14xXV8gY29udGFpbnMgYSB0ZWNobmljYWwgb3V0bGluZSBvZiBob3cgdGhlICoqQXB0ZXJvdXNbXjJdKiogcmF0aW5nIHN5c3RlbSBpcyBpbXBsZW1lbnRlZC4gSW4gcGFydGljdWxhciwgaXQgZXhwbGFpbnMgaG93IHRvIGNhbGN1bGF0ZSBob3cgbXVjaCBhIHBsYXllcidzIHJhdGluZyBjaGFuZ2VzIGFmdGVyIHdpbm5pbmcgb3IgbG9zaW5nIGEgZ2FtZS4gVGhpcyBjaGFuZ2UgaW4gcmF0aW5nIGlzIGtub3duIGFzICRcRGVsdGEgciQgKCJkZWx0YS1yIiksIGFuZCBpcyBwb3NpdGl2ZSBmb3IgYSB3aW4gYW5kIG5lZ2F0aXZlIGZvciBhIGxvc3MuIEluIHRoaXMgZG9jdW1lbnQsIEkgcHJvdmlkZSBhIGdyYXBoaWNhbCByZXByZXNlbnRhdGlvbiBvZiBob3cgJFxEZWx0YSByJCB2YXJpZXMgYmFzZWQgb24gdGhlIHJhdGluZ3Mgb2YgdGhlIHBsYXllcnMgaW4gYSBnYW1lLCBhbmQgdGhlIG1hcmdpbiBvZiB2aWN0b3J5IChvciBkZWZlYXQpIGluIHRoZSBnYW1lLiBUaGVyZSBhcmUgdHdvIG1hc3RlciBwbG90cyB3aGljaCBpbmNsdWRlIGEgdmVyeSB3aWRlIHJhbmdlIG9mIHBsYXllciByYXRpbmdzIGFuZCBtYXJnaW5zIG9mIHZpY3RvcnkgYW5kIGRlZmVhdC4gVGhlc2UgYXJlIGZvbGxvd2VkIGJ5IHN1YiBwbG90cyB3aGljaCB6b29tIGluIG9uIHRoZSBtYXN0ZXIgcGxvdHMgYW5kIGZvY3VzIG9uIGNvbWJpbmF0aW9ucyBvZiBwbGF5ZXIgcmF0aW5ncyBhbmQgbWFyZ2lucyBvZiB2aWN0b3J5IHRoYXQgbWlnaHQgYmUgZW5jb3VudGVyZWQgbW9yZSBvZnRlbi4KClteMV06IGh0dHA6Ly9hcHRlcm91cy5vcmcvcmF0aW5ncy5wZGYKW14yXTogaHR0cHM6Ly93d3cuYXB0ZXJvdXMub3JnLwoKKioqCgojIFRlY2huaWNhbCBEZXRhaWxzCgpUaGUgcHJlY2lzZSBkZXRhaWxzIG9uIGhvdyB0byBjYWxjdWxhdGUgJFxEZWx0YSByJCBhcmUgY29udGFpbmVkIGluIENoYXJsaWUncyBkb2N1bWVudC4gSSBwcm92aWRlIGEgc3VtbWFyeSBvZiB0aGVtIGluIHRoaXMgc2VjdGlvbi4KCiMjIENhbGN1bGF0aW5nICRcRGVsdGEgciQKCldlIGNhbGN1bGF0ZSB0aGUgY2hhbmdlIGluIHJhdGluZyBhcwokJApcRGVsdGEgciA9IGJjcGwsCiQkCndoZXJlOgoKKiAkYiQgaXMgdGhlIGJhc2UgcmF0aW5nIGNoYW5nZSwgZ2l2ZW4gYnkgJGIgPSBcYWxwaGEgKyBcYmV0YXxtfCQsIHdoZXJlICRtJCBpcyB0aGUgbWFyZ2luIG9mIHZpY3RvcnkuCiogJGMkIGlzIHRoZSBjb21wZW5zYXRpb24gZmFjdG9yIGZvciB0aGUgb3JpZ2luYWwgcmF0aW5ncyBkaWZmZXJlbmNlLiBUaGlzIGlzIGludGVuZGVkIHRvIHJld2FyZCBwbGF5ZXJzIG1vcmUgZm9yIGJlYXRpbmcgcGxheWVycyByYXRlZCBhYm92ZSB0aGVtLCBhbmQgcHVuaXNoIHRoZW0gbGVzcyBmb3IgbG9zaW5nIHRvIHN1Y2ggcGxheWVycy4gSXQgaXMgZGVmaW5lZCBhcwokJApjID0gdyAtIFxmcmFjezF9ezEgKyBcZXhwKFxnYW1tYShyX3tQMX0gLSByX3tQMn0pKX0sCiQkCndoZXJlICRyX3tQMX0kIGFyZSB0aGUgcmF0aW5ncyBmb3IgcGxheWVycyBvbmUgYW5kIHR3bywgYW5kICR3JCBpcyBkZWZpbmVkIGFzCiQkCncgPSBcYmVnaW57Y2FzZXN9MSAmIFx0ZXh0e2ZvciB0aGUgd2lubmVyfSBcXDEvMiAmIFx0ZXh0e2ZvciBkcmF3c30gXFwgMCAmIFx0ZXh0e2ZvciB0aGUgbG9zZXJ9XGVuZHtjYXNlc30KJCQKCiogJHAkIGlzIHRoZSBwcm92aXNpb25hbGl0eSBmYWN0b3IuIEluIHRoaXMgZG9jdW1lbnQgd2Ugd2lsbCBvbmx5IGNvbnNpZGVyIGZ1bGx5IHJhdGVkIHBsYXllcnMsIGluIHdoaWNoIGNhc2UgJHAgPSAxJC4KKiAkbCQgaXMgaXMgdGhlIGxlbmd0aCBmYWN0b3IsIHdoaWNoIGVzc2VudGlhbGx5IG1lYXN1cmVzIGhvdyBsb25nIHRoZSBnYW1lIHdhcy4gQ2xlYXJseSBhIDE1LXJvdW5kIGdhbWUgaXMgZmFyIG1vcmUgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCB0aGFuIGEgMS0gcm91bmQgY29udW5kcnVtIGF0dGFjaywgYW5kIHRoZSByYXRpbmcgY2hhbmdlIHJlZmxlY3RzIHRoaXMuIEl0IGlzIGRlZmluZWQgYXMgCiQkCmwgPSBcbXUgXGxuKDEgKyBuKQokJAp3aGVyZSAkbiQgaXMgdGhlIG51bWJlciBvZiByb3VuZHMgaW4gdGhlIGdhbWUuICRsJCBpcyBhbHNvIGNhcHBlZCBhdCAkXGxhbWJkYSQsIHNvIHRoYXQgZXZlbiBlbm9ybW91c2x5IGxvbmcgZ2FtZXMgY2Fubm90IGNhdXNlIGh1Z2UgcmF0aW5ncyBzd2luZ3MuIFRoZSB2YWx1ZSBvZiAkXG11JCBpbiBBcHRlcm91cyBpcyBzZXQgc28gdGhhdCAkbiA9IDE1JCBnaXZlcyAkbCA9IDEkLCBzbyB0aGlzIGZhY3RvciBlc3NlbnRpYWxseSBkaXNhcHBlYXJzIGZvciBzdGFuZGFyZCAxNS1yb3VuZCBnYW1lcy4KCiMjIENvbnN0YW50cwoKVGhlIGNvbnN0YW50cyB1c2VkIGFyZSBvdXRsaW5lZCBpbiB0aGUgYmVsb3cgdGFibGU6Cgp8IENvbnN0YW50IHwgVmFsdWUgICAgICAgICAgICAgfAp8LS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tfAp8ICRcYWxwaGEkIHwgMjAgICAgICAgICAgICAgICAgfAp8ICRcYmV0YSQgIHwgMS8yICAgICAgICAgICAgICAgfAp8ICRcZ2FtbWEkIHwgMC4wMDU3NSAgICAgICAgICAgfAp8ICRcbGFtYmRhJHwgMiAgICAgICAgICAgICAgICAgfAp8ICRcbXUkICAgIHwgMS9sbjE2ID0gMC4zNjEuLi4gfAp8ICRcc2lnbWEkIHwgNjAwICAgICAgICAgICAgICAgfAp8ICRcdGF1JCAgIHwgMTMzICAgICAgICAgICAgICAgfAp8ICRcb21lZ2EkIHwgMTEgICAgICAgICAgICAgICAgfAoKCiMjIEFzc3VtcHRpb25zCgpUaGVyZSBhcmUgYSBudW1iZXIgb2YgYXNzdW1wdGlvbnMgbWFkZSBoZXJlaW4gd2hpY2ggcmVsYXRlIHRvIGhvdyB0aGUgY2FsY3VsYXRpb25zIGFyZSBtYWRlOgoKLSAqKkFsbCBwbGF5ZXJzIGFyZSBhc3N1bWVkIHRvIGJlIGZ1bGx5IHJhdGVkKiogKCRwID0gMSQpOyBwcm92aXNpb25hbGx5IHJhdGVkIHBsYXllcnMgYXJlIG5vdCBpbmNsdWRlZC4KLSAqKk9ubHkgd2lucyBhbmQgbG9zc2VzIGFyZSBjb25zaWRlcmVkKiosIGRyYXdzIGFyZSBpZ25vcmVkICgkdyA9IDEkIGZvciBhIHdpbjsgJHcgPSAwJCBmb3IgYSBsb3NzKS4KLSAqKk9ubHkgZ2FtZXMgb2YgMTUgcm91bmRzIGFyZSBjb25zaWRlcmVkICgkbiA9IDE1JCkqKi4gTm90ZSB0aGF0IGl0IGRvZXNuJ3QgbWF0dGVyIGlmIHlvdSBwbGF5IG90aGVyIGdhbWVzIG9mIG1vcmUgb3IgbGVzcyB0aGFuIDE1IHJvdW5kcy4gUmF0aGVyLCB0aGUgYmVsb3cgdmlzdWFsaXNhdGlvbnMgb2YgJFxEZWx0YSByJCBhcmUgb25seSB2YWxpZCBmb3IgYSAxNSByb3VuZCBnYW1lLiAqKjxhIGhyZWY9IiNBcHBlbmRpeF9BIj5BcHBlbmRpeCBBPC9hPioqIHNob3dzIGluIGRldGFpbCBob3cgJFxEZWx0YSByJCB3b3VsZCB2YXJ5IGRlcGVuZGluZyBvbiB0aGUgbnVtYmVyIG9mIHJvdW5kcyBwbGF5ZWQsIGFuZCBwcm92aWRlcyBhIG11bHRpcGxlciB2YWx1ZSAoJGwkKSBmb3IgZGlmZmVyZW50IGxlbmd0aHMgb2YgZ2FtZXMgKCRsID0gMSQgZm9yIGEgMTUgcm91bmQgZ2FtZSkuIE5vdGUgaG93ZXZlciB0aGF0IHRoZSBtdWx0aXBsaWVyIGlzIGNhcHBlZCBhdCAkbCA9IDIkLCBzbyB0aGF0IGdhbWVzIG9mIDI1NSByb3VuZHMgb3IgbW9yZSBoYXZlIHRoZSBzYW1lIGVmZmVjdC4gR2FtZXMgb2YgbGVzcyB0aGFuIDI1NSByb3VuZHMgaGF2ZSBhIG11bHRpcGxpZXIgdmFsdWUgYmV0d2VlbiAwIGFuZCAyLiBUaGUgbmF0dXJlIG9mIHRoZSBtdWx0aXBsaWVyIGlzIHN1Y2ggdGhhdCB5b3UgaGF2ZSB0byBwbGF5IHF1aXRlIGEgbG9uZyBnYW1lIHRvIGhhdmUgYSBzaWduaWZpY2FudCBlZmZlY3Qgb24gdGhlIHJhdGluZy4gVGhlcmVmb3JlLCB0aGUgcmF0aW5ncyBvZiB0aGUgcGxheWVycyBhbmQgdGhlIG1hcmdpbiBvZiB2aWN0b3J5IGFyZSBtb3JlIHJlbGV2YW50IHRvIGNhbGN1bGF0aW5nICRcRGVsdGEgciQsIGJ1dCBkZXRhaWxzIG9mICRsJCBhcmUgaW5jbHVkZWQgZm9yIHJlZmVyZW5jZS4gKipGb3Igbm93IHRob3VnaCwgdGhlIG9ubHkgdGhpbmcgdG8gbm90ZSBpcyB0aGF0IHRoZSBiZWxvdyBwbG90cyBhc3N1bWUgZ2FtZXMgb2YgMTUgcm91bmRzKiouCgoqKioKCiMgUGxvdHMKCkFsbCBvZiB0aGUgYmVsb3cgcGxvdHMgYXJlIGNvbnRvdXIgcGxvdHMgd2l0aCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHBsYXllciByYXRpbmdzICgkcl97UDJ9LXJfe1AxfSQpIG9uIHRoZSB4LWF4aXMsIG1hcmdpbiBvZiB2aWN0b3J5IG9yIGRlZmVhdCAoJG0kKSBvbiB0aGUgeS1heGlzLCBhbmQgJFxEZWx0YSByJCBzaG93biBvbiB0aGUgY29udG91ciBsaW5lcy4gTm90ZSB0aGF0IGluIGNhbGN1bGF0aW5nIHRoZSBkaWZmZXJlbmNlIGluIHBsYXllciByYXRpbmdzLCB5b3UgbXVzdCAqKnN1YnRyYWN0IHlvdXIgcmF0aW5nKiogZnJvbSB5b3VyIG9wcG9uZW50J3MgcmF0aW5nIGluIG9yZGVyIGZvciB0aGUgcGxvdCB0byBiZSB2YWxpZCBmb3IgeW91LiBUaGUgZGlmZmVyZW5jZSB3aWxsIGJlIG5lZ2F0aXZlIGlmIHlvdSBhcmUgdGhlIGhpZ2hlciByYXRlZCBwbGF5ZXIgYW5kIHBvc2l0aXZlIGlmIHlvdSBhcmUgdGhlIGxvd2VyIHJhdGVkIHBsYXllci4gRm9yIHRoZSBtYXJnaW4gb2YgdmljdG9yeSBvciBkZWZlYXQgdGhlIHNpZ24gZG9lcyAqKm5vdCoqIG1hdHRlciwgc28gJG0kIGlzIGFsd2F5cyBwb3NpdGl2ZS4gU2VlICoqPGEgaHJlZj0iI0FwcGVuZGl4X0IiPkFwcGVuZGl4IEI8L2E+KiogZm9yIGFuIGV4YW1wbGUgd2hpY2ggaW5jbHVkZXMgaW5zdHJ1Y3Rpb25zIG9uIHJlYWRpbmcgYSBjb250b3VyIHBsb3QuCgpJbiBhbGwgb2YgdGhlIHBsb3RzICoqeW91IGFyZSBwbGF5ZXIgMSAoUDEpKiogYW5kIHlvdXIgb3Bwb25lbnQgaXMgcGxheWVyIDIgKFAyKS4gVGhlcmUgYXJlIHR3byBwbG90cyBmb3IgZWFjaCBzY2VuYXJpbywgb25lIGZvciBQMSB3aW5uaW5nICgqKlAxIFdpbnMqKiksIGFuZCBvbmUgZm9yIFAxIGxvc2luZyAoKipQMSBMb3NlcyoqKS4KCioqKgoKIyBNYXN0ZXIgUGxvdHMgIAoKVGhlc2UgdHdvIHBsb3RzIHNob3cgYSB2ZXJ5IHdpZGUgcmFuZ2Ugb2YgcGxheWVyIHJhdGluZ3MgYW5kIG1hcmdpbnMgb2YgdmljdG9yeSBhbmQgZGVmZWF0LiBUaGV5IGFyZSB1c2VmdWwgZm9yIGdldHRpbmcgYSBicm9hZCBvdmVydmlldyBvZiBob3cgdGhlIHJhdGluZ3MgY2hhbmdlLCBpbmNsdWRpbmcgd2hhdCBoYXBwZW5zIGluIGV4dHJlbWUgc2NlbmFyaW9zIHdoZXJlIGEgbG93ZXIgcmF0ZWQgcGxheWVyIGRlZmVhdHMgYSBoaWdoZXIgcmF0ZWQgcGxheWVyIGJ5IGEgbGFyZ2UgbWFyZ2luLgoKIyMgUDEgV2lucwpgYGB7ciBlY2hvPUZBTFNFLCBmaWcud2lkdGg9MTIsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMjIyB4LSBhbmQgeS1heGlzCmRpZmYgPC0gc2VxKC02NTAsIDEyNTAsIGJ5ID0gMTApCm0gPC0gc2VxKDEsIDE1MCwgbGVuZ3RoID0gbGVuZ3RoKGRpZmYpKQoKIyMjIFZhcmlhYmxlcwp3IDwtIDEgIyAoUDEgd2lucykKbiA8LSAxNQpiIDwtIGFscGhhICsgYmV0YSAqIG0KYyA8LSB3IC0gMSAvICgxICsgZXhwKGdhbW1hKihkaWZmKSkpCnAgPC0gMQpsIDwtIG11ICogbG9nKDEgKyBuKQoKZGVsdGEuciA8LSBvdXRlcihiLCBjLCBmdW5jdGlvbih4LCB5KSB4KnkqcCpsKQpkaW1uYW1lcyhkZWx0YS5yKSA8LSBsaXN0KHJvdW5kKG0sIDMpLCBkaWZmKSAKCmRlbHRhLnIgPC0gZGVsdGEuciAlPiUgCiAgbWVsdCgpICU+JSAKICBtdXRhdGUoZGlmZiA9IFgyLAogICAgICAgICBtID0gWDEsCiAgICAgICAgIGRlbHRhID0gdmFsdWUpICU+JSAKICBkcGx5cjo6c2VsZWN0KGRpZmYsIG0sIGRlbHRhKQoKZzEgPC0gZ2dwbG90KGRlbHRhLnIsIGFlcyhkaWZmLCBtKSkgKwogIGdlb21fcmFzdGVyKGludGVycG9sYXRlID0gVFJVRSwgYWVzKGZpbGwgPSBkZWx0YSkpICsKICBzY2FsZV9maWxsX2Rpc3RpbGxlcihuYW1lID0gYnF1b3RlKH4gRGVsdGEgfiByIH4gIihQMSkiKSwgdHlwZSA9ICJkaXYiLCBwYWxldHRlID0gNywgZGlyZWN0aW9uID0gLTEpICsKICBnZW9tX2NvbnRvdXIoYWVzKHogPSBkZWx0YSwgY29sb3IgPSAuLmxldmVsLi4pLCBjb2xvciA9ICJncmV5NTAiLCBicmVha3MgPSBjKDEsIDIsIDUsIHNlcSgxMCwgOTAsIGJ5ID0gMTApKSkgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYyhkaWZmWzFdLCBkaWZmW2xlbmd0aChkaWZmKV0pLCB5bGltID0gYyhtWzFdLCBtW2xlbmd0aChtKV0pLCBleHBhbmQgPSBGQUxTRSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoZGlmZlsxXSArIDUwLCBkaWZmW2xlbmd0aChkaWZmKV0sIGJ5ID0gMjAwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKDEsIHNlcSgxMCwgbVtsZW5ndGgobSldLCBieSA9IDEwKSkpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBzZXEoZGlmZlsxXSArIDUwLCBkaWZmW2xlbmd0aChkaWZmKV0sIGJ5ID0gMjAwKSwgY29sb3IgPSAiZ3JleTMwIiwgbGluZXR5cGUgPSAiZG90dGVkIikgKyAjIGdyaWQgbGluZXMKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBzZXEoMTAsIG1bbGVuZ3RoKG0pXSwgYnkgPSAxMCksIGNvbG9yID0gImdyZXkzMCIsIGxpbmV0eXBlID0gImRvdHRlZCIpICsgIyBncmlkIGxpbmVzCiAgdGhlbWVfYncoKSArCiAgbGFicyh0aXRsZSA9IFRlWCgiJFxcRGVsdGEgciQgZm9yIFxcdGV4dGJme1dpbn0iKSwKICAgICAgIGNhcHRpb24gPSBUZVgoIl5cdTIwMjAgcl97UFh9IGlzIHRoZSByYXRpbmcgXFx0ZXh0YmZ7ZW50ZXJpbmd9IHRoZSBnYW1lIGZvciBwbGF5ZXIgUFgiKSwKICAgICAgIHggPSBUZVgoInJfe1AyfSAtIHJfe1AxfSAgXlx1MjAyMCIpLAogICAgICAgeSA9ICJNYXJnaW4gb2YgVmljdG9yeSAobSkiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShzaXplID0gMSksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjAsIGhqdXN0ID0gMC41KSwKICAgICAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCB2anVzdCA9IC0wLjUpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpCiAgKQoKCmRpcmVjdC5sYWJlbChnMSwgbGlzdChjb2xvdXI9J2JsYWNrJywgImZhci5mcm9tLm90aGVycy5ib3JkZXJzIiwgImNhbGMuYm94ZXMiLCAiZW5sYXJnZS5ib3giLCAKICAgICAgaGp1c3QgPSAxLCB2anVzdCA9IDEuMiwgYm94LmNvbG9yID0gTkEsIGZpbGwgPSAidHJhbnNwYXJlbnQiLCAiZHJhdy5yZWN0cyIpKQpgYGAKCiMjIFAxIExvc2VzCmBgYHtyIGVjaG89RkFMU0UsIGZpZy53aWR0aD0xMiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyMjIHgtIGFuZCB5LWF4aXMKZGlmZiA8LSBzZXEoLTEyNTAsIDY1MCwgYnkgPSAxMCkKbSA8LSBzZXEoMSwgMTUwLCBsZW5ndGggPSBsZW5ndGgoZGlmZikpCgojIyMgVmFyaWFibGVzCncgPC0gMCAjIChQMSBsb3NlcykKbiA8LSAxNQpiIDwtIGFscGhhICsgYmV0YSAqIG0KYyA8LSB3IC0gMSAvICgxICsgZXhwKGdhbW1hKihkaWZmKSkpCnAgPC0gMQpsIDwtIG11ICogbG9nKDEgKyBuKQoKZGVsdGEuciA8LSBvdXRlcihiLCBjLCBmdW5jdGlvbih4LCB5KSB4KnkqcCpsKQpkaW1uYW1lcyhkZWx0YS5yKSA8LSBsaXN0KHJvdW5kKG0sIDMpLCBkaWZmKSAKCmRlbHRhLnIgPC0gZGVsdGEuciAlPiUgCiAgbWVsdCgpICU+JSAKICBtdXRhdGUoZGlmZiA9IFgyLAogICAgICAgICBtID0gWDEsCiAgICAgICAgIGRlbHRhID0gdmFsdWUpICU+JSAKICBkcGx5cjo6c2VsZWN0KGRpZmYsIG0sIGRlbHRhKQoKZzIgPC0gZ2dwbG90KGRlbHRhLnIsIGFlcyhkaWZmLCBtKSkgKwogIGdlb21fcmFzdGVyKGludGVycG9sYXRlID0gVFJVRSwgYWVzKGZpbGwgPSBkZWx0YSkpICsKICBzY2FsZV9maWxsX2Rpc3RpbGxlcihuYW1lID0gYnF1b3RlKH4gRGVsdGEgfiByIH4gIihQMSkiKSwgdHlwZSA9ICJkaXYiLCBwYWxldHRlID0gNywgZGlyZWN0aW9uID0gMSkgKwogIGdlb21fY29udG91cihhZXMoeiA9IGRlbHRhLCBjb2xvciA9IC4ubGV2ZWwuLiksIGNvbG9yID0gImdyZXk1MCIsIGJyZWFrcyA9IGMoc2VxKC05MCwgLTEwLCBieSA9IDEwKSwgLTUsIC0yLCAtMSkpICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoZGlmZlsxXSwgZGlmZltsZW5ndGgoZGlmZildKSwgeWxpbSA9IGMobVsxXSwgbVtsZW5ndGgobSldKSwgZXhwYW5kID0gRkFMU0UpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKGRpZmZbMV0gKyA1MCwgZGlmZltsZW5ndGgoZGlmZildLCBieSA9IDIwMCkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygxLCBzZXEoMTAsIG1bbGVuZ3RoKG0pXSwgYnkgPSAxMCkpKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gc2VxKGRpZmZbMV0gKyA1MCwgZGlmZltsZW5ndGgoZGlmZildLCBieSA9IDIwMCksIGNvbG9yID0gImdyZXkzMCIsIGxpbmV0eXBlID0gImRvdHRlZCIpICsgIyBncmlkIGxpbmVzCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gc2VxKDEwLCBtW2xlbmd0aChtKV0sIGJ5ID0gMTApLCBjb2xvciA9ICJncmV5MzAiLCBsaW5ldHlwZSA9ICJkb3R0ZWQiKSArICMgZ3JpZCBsaW5lcwogIHRoZW1lX2J3KCkgKwogIGxhYnModGl0bGUgPSBUZVgoIiRcXERlbHRhIHIkIGZvciBcXHRleHRiZntMb3NzfSIpLAogICAgICAgY2FwdGlvbiA9IFRlWCgiXlx1MjAyMCByX3tQWH0gaXMgdGhlIHJhdGluZyBcXHRleHRiZntlbnRlcmluZ30gdGhlIGdhbWUgZm9yIHBsYXllciBQWCIpLAogICAgICAgeCA9IFRlWCgicl97UDJ9IC0gcl97UDF9ICBeXHUyMDIwIiksCiAgICAgICB5ID0gIk1hcmdpbiBvZiBEZWZlYXQgKG0pIikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoc2l6ZSA9IDEpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwLCBoanVzdCA9IDAuNSksCiAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCwgdmp1c3QgPSAtMC41KSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKQogICkKCmRpcmVjdC5sYWJlbChnMiwgbGlzdChjb2xvdXI9J2JsYWNrJywgImZhci5mcm9tLm90aGVycy5ib3JkZXJzIiwgImNhbGMuYm94ZXMiLCAiZW5sYXJnZS5ib3giLCAKICAgICAgaGp1c3QgPSAxLCB2anVzdCA9IDEuMiwgYm94LmNvbG9yID0gTkEsIGZpbGwgPSAidHJhbnNwYXJlbnQiLCAiZHJhdy5yZWN0cyIpKQpgYGAKCioqKgoKIyBTdWIgUGxvdHMKCiMjIFNpbWlsYXJseSBSYXRlZCBQbGF5ZXJzCgpUaGVzZSBwbG90cyB6b29tIGluIG9uIGJvdGggYXhlcyBhbmQgYXJlIHN1aXRhYmxlIGZvciBwbGF5ZXJzIHdobyBmaW5kIHRoZW1zZWx2ZXMgcGxheWluZyBvcHBvbmVudHMgd2l0aCBhIHNpbWlsYXIgcmF0aW5nIHRvIHRoZWlyIG93biAoJFxwbSQgNDAwIHBvaW50cykuIEluIHRoaXMgY2FzZSB0aGUgbWFyZ2luIG9mIHZpY3RvcnkgKG9yIGRlZmVhdCkgaXMgdGFrZW4gdG8gYmUgNTAgcG9pbnRzIG9yIGxlc3MgKHRoZSBtYXN0ZXIgcGxvdCBjYW4gYmUgdXNlZCBmb3Igd2lkZXIgbWFyZ2lucykuIAoKIyMjIFAxIFdpbnMgIAoKYGBge3IgZWNobz1GQUxTRSwgZmlnLndpZHRoPTEyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIyMgeC0gYW5kIHktYXhpcwpkaWZmIDwtIHNlcSgtNDEwLCA0MTAsIGJ5ID0gMTApCm0gPC0gc2VxKDEsIDUwLCBsZW5ndGggPSBsZW5ndGgoZGlmZikpCgojIyMgVmFyaWFibGVzCncgPC0gMSAjIChQMSB3aW5zKQpuIDwtIDE1CmIgPC0gYWxwaGEgKyBiZXRhICogbQpjIDwtIHcgLSAxIC8gKDEgKyBleHAoZ2FtbWEqKGRpZmYpKSkKcCA8LSAxCmwgPC0gbXUgKiBsb2coMSArIG4pCgpkZWx0YS5yIDwtIG91dGVyKGIsIGMsIGZ1bmN0aW9uKHgsIHkpIHgqeSpwKmwpCmRpbW5hbWVzKGRlbHRhLnIpIDwtIGxpc3Qocm91bmQobSwgMyksIGRpZmYpIAoKZGVsdGEuciA8LSBkZWx0YS5yICU+JSAKICBtZWx0KCkgJT4lIAogIG11dGF0ZShkaWZmID0gWDIsCiAgICAgICAgIG0gPSBYMSwKICAgICAgICAgZGVsdGEgPSB2YWx1ZSkgJT4lIAogIGRwbHlyOjpzZWxlY3QoZGlmZiwgbSwgZGVsdGEpCgpnNyA8LSBnZ3Bsb3QoZGVsdGEuciwgYWVzKGRpZmYsIG0pKSArCiAgZ2VvbV9yYXN0ZXIoaW50ZXJwb2xhdGUgPSBUUlVFLCBhZXMoZmlsbCA9IGRlbHRhKSkgKwogIHNjYWxlX2ZpbGxfZGlzdGlsbGVyKG5hbWUgPSBicXVvdGUofiBEZWx0YSB+IHIgfiAiKFAxKSIpLCB0eXBlID0gImRpdiIsIHBhbGV0dGUgPSA3LCBkaXJlY3Rpb24gPSAtMSkgKwogIGdlb21fY29udG91cihhZXMoeiA9IGRlbHRhLCBjb2xvciA9IC4ubGV2ZWwuLiksIGNvbG9yID0gImdyZXk1MCIsIGJpbndpZHRoID0gMikgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYyhkaWZmWzFdLCBkaWZmW2xlbmd0aChkaWZmKV0pLCB5bGltID0gYyhtWzFdLCBtW2xlbmd0aChtKV0pLCBleHBhbmQgPSBGQUxTRSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoZGlmZlsxXSArIDEwLCBkaWZmW2xlbmd0aChkaWZmKV0sIGJ5ID0gNTApKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoMSwgc2VxKDEwLCBtW2xlbmd0aChtKV0sIGJ5ID0gMTApKSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IHNlcShkaWZmWzFdICsgMTAsIGRpZmZbbGVuZ3RoKGRpZmYpXSwgYnkgPSA1MCksIGNvbG9yID0gImdyZXkzMCIsIGxpbmV0eXBlID0gImRvdHRlZCIpICsgIyBncmlkIGxpbmVzCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdCA9IDApLCBjb2xvciA9ICJncmV5NTAiKSArICMgeS1heGlzCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gc2VxKDEwLCBtW2xlbmd0aChtKV0sIGJ5ID0gMTApLCBjb2xvciA9ICJncmV5MzAiLCBsaW5ldHlwZSA9ICJkb3R0ZWQiKSArICMgZ3JpZCBsaW5lcwogIHRoZW1lX2J3KCkgKwogIGxhYnModGl0bGUgPSBUZVgoIiRcXERlbHRhIHIkIGZvciBcXHRleHRiZntXaW59IiksCiAgICAgICBzdWJ0aXRsZSA9ICJBIHBsYXllciBvZiBhbnkgcmF0aW5nIHdpbnMgYWdhaW5zdCBhIHNpbWlsYXJseSByYXRlZCBwbGF5ZXIiLAogICAgICAgeCA9IFRlWCgicl97UDJ9IC0gcl97UDF9IiksCiAgICAgICB5ID0gIk1hcmdpbiBvZiBWaWN0b3J5IChtKSIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKHNpemUgPSAxKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLAogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgsIHZqdXN0ID0gLTAuNSksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMikKICApCgpkaXJlY3QubGFiZWwoZzcsIGxpc3QoY29sb3VyPSdibGFjaycsICJmYXIuZnJvbS5vdGhlcnMuYm9yZGVycyIsICJjYWxjLmJveGVzIiwgImVubGFyZ2UuYm94IiwgCiAgICAgIGhqdXN0ID0gMSwgdmp1c3QgPSAxLjUsIGJveC5jb2xvciA9IE5BLCBmaWxsID0gInRyYW5zcGFyZW50IiwgImRyYXcucmVjdHMiKSkKYGBgCgojIyMgUDEgTG9zZXMgIAoKYGBge3IgZWNobz1GQUxTRSwgZmlnLndpZHRoPTEyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIyMgeC0gYW5kIHktYXhpcwpkaWZmIDwtIHNlcSgtNDEwLCA0MTAsIGJ5ID0gMTApCm0gPC0gc2VxKDEsIDUwLCBsZW5ndGggPSBsZW5ndGgoZGlmZikpCgojIyMgVmFyaWFibGVzCncgPC0gMCAjIChQMSBsb3NlcykKbiA8LSAxNQpiIDwtIGFscGhhICsgYmV0YSAqIG0KYyA8LSB3IC0gMSAvICgxICsgZXhwKGdhbW1hKihkaWZmKSkpCnAgPC0gMQpsIDwtIG11ICogbG9nKDEgKyBuKQoKZGVsdGEuciA8LSBvdXRlcihiLCBjLCBmdW5jdGlvbih4LCB5KSB4KnkqcCpsKQpkaW1uYW1lcyhkZWx0YS5yKSA8LSBsaXN0KHJvdW5kKG0sIDMpLCBkaWZmKSAKCmRlbHRhLnIgPC0gZGVsdGEuciAlPiUgCiAgbWVsdCgpICU+JSAKICBtdXRhdGUoZGlmZiA9IFgyLAogICAgICAgICBtID0gWDEsCiAgICAgICAgIGRlbHRhID0gdmFsdWUpICU+JSAKICBkcGx5cjo6c2VsZWN0KGRpZmYsIG0sIGRlbHRhKQoKZzggPC0gZ2dwbG90KGRlbHRhLnIsIGFlcyhkaWZmLCBtKSkgKwogIGdlb21fcmFzdGVyKGludGVycG9sYXRlID0gVFJVRSwgYWVzKGZpbGwgPSBkZWx0YSkpICsKICBzY2FsZV9maWxsX2Rpc3RpbGxlcihuYW1lID0gYnF1b3RlKH4gRGVsdGEgfiByIH4gIihQMSkiKSwgdHlwZSA9ICJkaXYiLCBwYWxldHRlID0gNywgZGlyZWN0aW9uID0gMSkgKwogIGdlb21fY29udG91cihhZXMoeiA9IGRlbHRhLCBjb2xvciA9IC4ubGV2ZWwuLiksIGNvbG9yID0gImdyZXk1MCIsIGJpbndpZHRoID0gMikgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYyhkaWZmWzFdLCBkaWZmW2xlbmd0aChkaWZmKV0pLCB5bGltID0gYyhtWzFdLCBtW2xlbmd0aChtKV0pLCBleHBhbmQgPSBGQUxTRSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoZGlmZlsxXSArIDEwLCBkaWZmW2xlbmd0aChkaWZmKV0sIGJ5ID0gNTApKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoMSwgc2VxKDEwLCBtW2xlbmd0aChtKV0sIGJ5ID0gMTApKSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IHNlcShkaWZmWzFdICsgMTAsIGRpZmZbbGVuZ3RoKGRpZmYpXSwgYnkgPSA1MCksIGNvbG9yID0gImdyZXkzMCIsIGxpbmV0eXBlID0gImRvdHRlZCIpICsgIyBncmlkIGxpbmVzCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdCA9IDApLCBjb2xvciA9ICJncmV5NTAiKSArICMgeS1heGlzCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gc2VxKDEwLCBtW2xlbmd0aChtKV0sIGJ5ID0gMTApLCBjb2xvciA9ICJncmV5MzAiLCBsaW5ldHlwZSA9ICJkb3R0ZWQiKSArICMgZ3JpZCBsaW5lcwogIHRoZW1lX2J3KCkgKwogIGxhYnModGl0bGUgPSBUZVgoIiRcXERlbHRhIHIkIGZvciBcXHRleHRiZntMb3NzfSIpLAogICAgICAgc3VidGl0bGUgPSAiQSBwbGF5ZXIgb2YgYW55IHJhdGluZyBsb3NlcyBhZ2FpbnN0IGEgc2ltaWxhcmx5IHJhdGVkIHBsYXllciIsCiAgICAgICB4ID0gVGVYKCJyX3tQMn0gLSByX3tQMX0iKSwKICAgICAgIHkgPSAiTWFyZ2luIG9mIERlZmVhdCAobSkiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShzaXplID0gMSksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLAogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCB2anVzdCA9IC0wLjUpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpCiAgKQoKZGlyZWN0LmxhYmVsKGc4LCBsaXN0KGNvbG91cj0nYmxhY2snLCAiZmFyLmZyb20ub3RoZXJzLmJvcmRlcnMiLCAiY2FsYy5ib3hlcyIsICJlbmxhcmdlLmJveCIsIAogICAgICBoanVzdCA9IDEsIHZqdXN0ID0gMS41LCBib3guY29sb3IgPSBOQSwgZmlsbCA9ICJ0cmFuc3BhcmVudCIsICJkcmF3LnJlY3RzIikpCmBgYAoKIyMgTG93ZXIgUmF0ZWQgUGxheWVyIChQMSkgLVZTLSBIaWdoZXIgUmF0ZWQgUGxheWVyIChQMikKClRoZXNlIHBsb3RzIGFyZSBzdWl0YWJsZSBmb3IgdGhvc2Ugd2hvIGZpbmQgdGhlbXNlbHZlcyBwbGF5aW5nIGFnYWluc3Qgb3Bwb25lbnRzIHdobyBhcmUgcmF0ZWQgd2VsbCBhYm92ZSB0aGVtLiBJbiB0aGlzIHNjZW5hcmlvLCBQMSBjYW4gZ2FpbiBhIGxvdCBvZiByYXRpbmcgcG9pbnRzIGZvciBhIHdpbiBhZ2FpbnN0IGEgaGlnaGx5IHJhdGVkIHBsYXllciwgYnV0IGNhbid0IGxvc2UgbWFueSByYXRpbmcgcG9pbnRzLiBUaGUgbGltaXRzIG9uIHRoZSBheGVzIHJlZmxlY3QgdGhpcy4KCiMjIyBQMSBXaW5zCgpgYGB7ciBlY2hvPUZBTFNFLCBmaWcud2lkdGg9MTIsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMjIyB4LSBhbmQgeS1heGlzCmRpZmYgPC0gc2VxKC0xMTAsIDgxMCwgYnkgPSAxMCkKbSA8LSBzZXEoMSwgNTAsIGxlbmd0aCA9IGxlbmd0aChkaWZmKSkKCiMjIyBWYXJpYWJsZXMKdyA8LSAxICMgKFAxIHdpbnMpCm4gPC0gMTUKYiA8LSBhbHBoYSArIGJldGEgKiBtCmMgPC0gdyAtIDEgLyAoMSArIGV4cChnYW1tYSooZGlmZikpKQpwIDwtIDEKbCA8LSBtdSAqIGxvZygxICsgbikKCmRlbHRhLnIgPC0gb3V0ZXIoYiwgYywgZnVuY3Rpb24oeCwgeSkgeCp5KnAqbCkKZGltbmFtZXMoZGVsdGEucikgPC0gbGlzdChyb3VuZChtLCAzKSwgZGlmZikgCgpkZWx0YS5yIDwtIGRlbHRhLnIgJT4lIAogIG1lbHQoKSAlPiUgCiAgbXV0YXRlKGRpZmYgPSBYMiwKICAgICAgICAgbSA9IFgxLAogICAgICAgICBkZWx0YSA9IHZhbHVlKSAlPiUgCiAgZHBseXI6OnNlbGVjdChkaWZmLCBtLCBkZWx0YSkKCmczIDwtIGdncGxvdChkZWx0YS5yLCBhZXMoZGlmZiwgbSkpICsKICBnZW9tX3Jhc3RlcihpbnRlcnBvbGF0ZSA9IFRSVUUsIGFlcyhmaWxsID0gZGVsdGEpKSArCiAgc2NhbGVfZmlsbF9kaXN0aWxsZXIobmFtZSA9IGJxdW90ZSh+IERlbHRhIH4gciB+ICIoUDEpIiksIHR5cGUgPSAiZGl2IiwgcGFsZXR0ZSA9IDcsIGRpcmVjdGlvbiA9IC0xKSArCiAgZ2VvbV9jb250b3VyKGFlcyh6ID0gZGVsdGEsIGNvbG9yID0gLi5sZXZlbC4uKSwgY29sb3IgPSAiZ3JleTUwIiwgYmlud2lkdGggPSAyKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKGRpZmZbMV0sIGRpZmZbbGVuZ3RoKGRpZmYpXSksIHlsaW0gPSBjKG1bMV0sIG1bbGVuZ3RoKG0pXSksIGV4cGFuZCA9IEZBTFNFKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShkaWZmWzFdICsgMTAsIGRpZmZbbGVuZ3RoKGRpZmYpXSwgYnkgPSA1MCkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygxLCBzZXEoMTAsIG1bbGVuZ3RoKG0pXSwgYnkgPSAxMCkpKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gc2VxKGRpZmZbMV0gKyAxMCwgZGlmZltsZW5ndGgoZGlmZildLCBieSA9IDUwKSwgY29sb3IgPSAiZ3JleTMwIiwgbGluZXR5cGUgPSAiZG90dGVkIikgKyAjIGdyaWQgbGluZXMKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBzZXEoMTAsIG1bbGVuZ3RoKG0pXSwgYnkgPSAxMCksIGNvbG9yID0gImdyZXkzMCIsIGxpbmV0eXBlID0gImRvdHRlZCIpICsgIyBncmlkIGxpbmVzCiAgdGhlbWVfYncoKSArCiAgbGFicyh0aXRsZSA9IFRlWCgiJFxcRGVsdGEgciQgZm9yIFxcdGV4dGJme1dpbn0iKSwKICAgICAgIHN1YnRpdGxlID0gIkxvd2VyIHJhdGVkIHBsYXllciB3aW5zIGFnYWluc3QgYSBoaWdoZXIgcmF0ZWQgcGxheWVyIiwKICAgICAgIHggPSBUZVgoInJfe1AyfSAtIHJfe1AxfSIpLAogICAgICAgeSA9ICJNYXJnaW4gb2YgVmljdG9yeSAobSkiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShzaXplID0gMSksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLAogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCB2anVzdCA9IC0wLjUpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpCiAgKQoKZGlyZWN0LmxhYmVsKGczLCBsaXN0KGNvbG91cj0nYmxhY2snLCAiZmFyLmZyb20ub3RoZXJzLmJvcmRlcnMiLCAiY2FsYy5ib3hlcyIsICJlbmxhcmdlLmJveCIsIAogICAgICBoanVzdCA9IDEsIHZqdXN0ID0gMS41LCBib3guY29sb3IgPSBOQSwgZmlsbCA9ICJ0cmFuc3BhcmVudCIsICJkcmF3LnJlY3RzIikpCmBgYAoKCiMjIyBQMSBMb3NlcwoKYGBge3IgZWNobz1GQUxTRSwgZmlnLndpZHRoPTEyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIyMgeC0gYW5kIHktYXhpcwpkaWZmIDwtIHNlcSgtMTEwLCA4MTAsIGJ5ID0gMTApCm0gPC0gc2VxKDEsIDEwMCwgbGVuZ3RoID0gbGVuZ3RoKGRpZmYpKQoKIyMjIFZhcmlhYmxlcwp3IDwtIDAgIyAoUDEgbG9zZXMpCm4gPC0gMTUKYiA8LSBhbHBoYSArIGJldGEgKiBtCmMgPC0gdyAtIDEgLyAoMSArIGV4cChnYW1tYSooZGlmZikpKQpwIDwtIDEKbCA8LSBtdSAqIGxvZygxICsgbikKCmRlbHRhLnIgPC0gb3V0ZXIoYiwgYywgZnVuY3Rpb24oeCwgeSkgeCp5KnAqbCkKZGltbmFtZXMoZGVsdGEucikgPC0gbGlzdChyb3VuZChtLCAzKSwgZGlmZikgCgpkZWx0YS5yIDwtIGRlbHRhLnIgJT4lIAogIG1lbHQoKSAlPiUgCiAgbXV0YXRlKGRpZmYgPSBYMiwKICAgICAgICAgbSA9IFgxLAogICAgICAgICBkZWx0YSA9IHZhbHVlKSAlPiUgCiAgZHBseXI6OnNlbGVjdChkaWZmLCBtLCBkZWx0YSkKCmc0IDwtIGdncGxvdChkZWx0YS5yLCBhZXMoZGlmZiwgbSkpICsKICBnZW9tX3Jhc3RlcihpbnRlcnBvbGF0ZSA9IFRSVUUsIGFlcyhmaWxsID0gZGVsdGEpKSArCiAgc2NhbGVfZmlsbF9kaXN0aWxsZXIobmFtZSA9IGJxdW90ZSh+IERlbHRhIH4gciB+ICIoUDEpIiksIHR5cGUgPSAiZGl2IiwgcGFsZXR0ZSA9IDcsIGRpcmVjdGlvbiA9IDEpICsKICBnZW9tX2NvbnRvdXIoYWVzKHogPSBkZWx0YSwgY29sb3IgPSAuLmxldmVsLi4pLCBjb2xvciA9ICJncmV5NTAiLCBiaW53aWR0aCA9IDIpICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoZGlmZlsxXSwgZGlmZltsZW5ndGgoZGlmZildKSwgeWxpbSA9IGMobVsxXSwgbVtsZW5ndGgobSldKSwgZXhwYW5kID0gRkFMU0UpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKGRpZmZbMV0gKyAxMCwgZGlmZltsZW5ndGgoZGlmZildLCBieSA9IDUwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKDEsIHNlcSgxMCwgbVtsZW5ndGgobSldLCBieSA9IDEwKSkpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBzZXEoZGlmZlsxXSArIDEwLCBkaWZmW2xlbmd0aChkaWZmKV0sIGJ5ID0gNTApLCBjb2xvciA9ICJncmV5MzAiLCBsaW5ldHlwZSA9ICJkb3R0ZWQiKSArICMgZ3JpZCBsaW5lcwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IHNlcSgxMCwgbVtsZW5ndGgobSldLCBieSA9IDEwKSwgY29sb3IgPSAiZ3JleTMwIiwgbGluZXR5cGUgPSAiZG90dGVkIikgKyAjIGdyaWQgbGluZXMKICB0aGVtZV9idygpICsKICBsYWJzKHRpdGxlID0gVGVYKCIkXFxEZWx0YSByJCBmb3IgXFx0ZXh0YmZ7TG9zc30iKSwKICAgICAgIHN1YnRpdGxlID0gIkxvd2VyIHJhdGVkIHBsYXllciBsb3NlcyBhZ2FpbnN0IGEgaGlnaGVyIHJhdGVkIHBsYXllciIsCiAgICAgICB4ID0gVGVYKCJyX3tQMn0gLSByX3tQMX0iKSwKICAgICAgIHkgPSAiTWFyZ2luIG9mIERlZmVhdCAobSkiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShzaXplID0gMSksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLAogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCB2anVzdCA9IC0wLjUpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpCiAgKQoKZGlyZWN0LmxhYmVsKGc0LCBsaXN0KGNvbG91cj0nYmxhY2snLCAiZmFyLmZyb20ub3RoZXJzLmJvcmRlcnMiLCAiY2FsYy5ib3hlcyIsICJlbmxhcmdlLmJveCIsIAogICAgICBoanVzdCA9IDEsIHZqdXN0ID0gMS4yLCBib3guY29sb3IgPSBOQSwgZmlsbCA9ICJ0cmFuc3BhcmVudCIsICJkcmF3LnJlY3RzIikpCmBgYAoKCiMjIEhpZ2hlciBSYXRlZCBQbGF5ZXIgKFAxKSAtVlMtIExvd2VyIFJhdGVkIFBsYXllciAoUDIpCgpUaGVzZSBwbG90cyBhcmUgc3VpdGFibGUgZm9yIHRob3NlIHdobyBmaW5kIHRoZW1zZWx2ZXMgcGxheWluZyBhZ2FpbnN0IG9wcG9uZW50cyB3aG8gYXJlIHJhdGVkIHdlbGwgYmVsb3cgdGhlbS4gSW4gdGhpcyBzY2VuYXJpbywgUDEgY2FuJ3QgZ2FpbiBtYW55IHJhdGluZyBwb2ludHMgZm9yIGEgd2luIGFnYWluc3QgYSBsb3dlciByYXRlZCBwbGF5ZXIsIGJ1dCBjYW4gbG9zZSBhIGxvdCBvZiByYXRpbmcgcG9pbnRzIGZvciBhIGxvc3MuIFRoZSBsaW1pdHMgb24gdGhlIGF4ZXMgcmVmbGVjdCB0aGlzLgoKIyMjIFAxIFdpbnMKCmBgYHtyIGVjaG89RkFMU0UsIGZpZy53aWR0aD0xMiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyMjIHgtIGFuZCB5LWF4aXMKZGlmZiA8LSBzZXEoLTgxMCwgMTEwLCBieSA9IDEwKQptIDwtIHNlcSgxLCAxMDAsIGxlbmd0aCA9IGxlbmd0aChkaWZmKSkKCiMjIyBWYXJpYWJsZXMKdyA8LSAxICMgKFAxIHdpbnMpCm4gPC0gMTUKYiA8LSBhbHBoYSArIGJldGEgKiBtCmMgPC0gdyAtIDEgLyAoMSArIGV4cChnYW1tYSooZGlmZikpKQpwIDwtIDEKbCA8LSBtdSAqIGxvZygxICsgbikKCmRlbHRhLnIgPC0gb3V0ZXIoYiwgYywgZnVuY3Rpb24oeCwgeSkgeCp5KnAqbCkKZGltbmFtZXMoZGVsdGEucikgPC0gbGlzdChyb3VuZChtLCAzKSwgZGlmZikgCgpkZWx0YS5yIDwtIGRlbHRhLnIgJT4lIAogIG1lbHQoKSAlPiUgCiAgbXV0YXRlKGRpZmYgPSBYMiwKICAgICAgICAgbSA9IFgxLAogICAgICAgICBkZWx0YSA9IHZhbHVlKSAlPiUgCiAgZHBseXI6OnNlbGVjdChkaWZmLCBtLCBkZWx0YSkKCmc1IDwtIGdncGxvdChkZWx0YS5yLCBhZXMoZGlmZiwgbSkpICsKICBnZW9tX3Jhc3RlcihpbnRlcnBvbGF0ZSA9IFRSVUUsIGFlcyhmaWxsID0gZGVsdGEpKSArCiAgc2NhbGVfZmlsbF9kaXN0aWxsZXIobmFtZSA9IGJxdW90ZSh+IERlbHRhIH4gciB+ICIoUDEpIiksIHR5cGUgPSAiZGl2IiwgcGFsZXR0ZSA9IDcsIGRpcmVjdGlvbiA9IC0xKSArCiAgZ2VvbV9jb250b3VyKGFlcyh6ID0gZGVsdGEsIGNvbG9yID0gLi5sZXZlbC4uKSwgY29sb3IgPSAiZ3JleTUwIiwgYmlud2lkdGggPSAyKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKGRpZmZbMV0sIGRpZmZbbGVuZ3RoKGRpZmYpXSksIHlsaW0gPSBjKG1bMV0sIG1bbGVuZ3RoKG0pXSksIGV4cGFuZCA9IEZBTFNFKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShkaWZmWzFdICsgMTAsIGRpZmZbbGVuZ3RoKGRpZmYpXSwgYnkgPSA1MCkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygxLCBzZXEoMTAsIG1bbGVuZ3RoKG0pXSwgYnkgPSAxMCkpKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gc2VxKGRpZmZbMV0gKyAxMCwgZGlmZltsZW5ndGgoZGlmZildLCBieSA9IDUwKSwgY29sb3IgPSAiZ3JleTMwIiwgbGluZXR5cGUgPSAiZG90dGVkIikgKyAjIGdyaWQgbGluZXMKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBzZXEoMTAsIG1bbGVuZ3RoKG0pXSwgYnkgPSAxMCksIGNvbG9yID0gImdyZXkzMCIsIGxpbmV0eXBlID0gImRvdHRlZCIpICsgIyBncmlkIGxpbmVzCiAgdGhlbWVfYncoKSArCiAgbGFicyh0aXRsZSA9IFRlWCgiJFxcRGVsdGEgciQgZm9yIFxcdGV4dGJme1dpbn0iKSwKICAgICAgIHN1YnRpdGxlID0gIkhpZ2hlciByYXRlZCBwbGF5ZXIgd2lucyBhZ2FpbnN0IGEgbG93ZXIgcmF0ZWQgcGxheWVyIiwKICAgICAgIHggPSBUZVgoInJfe1AyfSAtIHJfe1AxfSIpLAogICAgICAgeSA9ICJNYXJnaW4gb2YgVmljdG9yeSAobSkiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShzaXplID0gMSksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLAogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCB2anVzdCA9IC0wLjUpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpCiAgKQoKZGlyZWN0LmxhYmVsKGc1LCBsaXN0KGNvbG91cj0nYmxhY2snLCAiZmFyLmZyb20ub3RoZXJzLmJvcmRlcnMiLCAiY2FsYy5ib3hlcyIsICJlbmxhcmdlLmJveCIsIAogICAgICBoanVzdCA9IDEsIHZqdXN0ID0gMS4yLCBib3guY29sb3IgPSBOQSwgZmlsbCA9ICJ0cmFuc3BhcmVudCIsICJkcmF3LnJlY3RzIikpCmBgYAoKIyMjIFAxIExvc2VzCgpgYGB7ciBlY2hvPUZBTFNFLCBmaWcud2lkdGg9MTIsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMjIyB4LSBhbmQgeS1heGlzCmRpZmYgPC0gc2VxKC04MTAsIDExMCwgYnkgPSAxMCkKbSA8LSBzZXEoMSwgNTAsIGxlbmd0aCA9IGxlbmd0aChkaWZmKSkKCiMjIyBWYXJpYWJsZXMKdyA8LSAwICMgKFAxIGxvc2VzKQpuIDwtIDE1CmIgPC0gYWxwaGEgKyBiZXRhICogbQpjIDwtIHcgLSAxIC8gKDEgKyBleHAoZ2FtbWEqKGRpZmYpKSkKcCA8LSAxCmwgPC0gbXUgKiBsb2coMSArIG4pCgpkZWx0YS5yIDwtIG91dGVyKGIsIGMsIGZ1bmN0aW9uKHgsIHkpIHgqeSpwKmwpCmRpbW5hbWVzKGRlbHRhLnIpIDwtIGxpc3Qocm91bmQobSwgMyksIGRpZmYpIAoKZGVsdGEuciA8LSBkZWx0YS5yICU+JSAKICBtZWx0KCkgJT4lIAogIG11dGF0ZShkaWZmID0gWDIsCiAgICAgICAgIG0gPSBYMSwKICAgICAgICAgZGVsdGEgPSB2YWx1ZSkgJT4lIAogIGRwbHlyOjpzZWxlY3QoZGlmZiwgbSwgZGVsdGEpCgpnNiA8LSBnZ3Bsb3QoZGVsdGEuciwgYWVzKGRpZmYsIG0pKSArCiAgZ2VvbV9yYXN0ZXIoaW50ZXJwb2xhdGUgPSBUUlVFLCBhZXMoZmlsbCA9IGRlbHRhKSkgKwogIHNjYWxlX2ZpbGxfZGlzdGlsbGVyKG5hbWUgPSBicXVvdGUofiBEZWx0YSB+IHIgfiAiKFAxKSIpLCB0eXBlID0gImRpdiIsIHBhbGV0dGUgPSA3LCBkaXJlY3Rpb24gPSAxKSArCiAgZ2VvbV9jb250b3VyKGFlcyh6ID0gZGVsdGEsIGNvbG9yID0gLi5sZXZlbC4uKSwgY29sb3IgPSAiZ3JleTUwIiwgYmlud2lkdGggPSAyKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKGRpZmZbMV0sIGRpZmZbbGVuZ3RoKGRpZmYpXSksIHlsaW0gPSBjKG1bMV0sIG1bbGVuZ3RoKG0pXSksIGV4cGFuZCA9IEZBTFNFKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShkaWZmWzFdICsgMTAsIGRpZmZbbGVuZ3RoKGRpZmYpXSwgYnkgPSA1MCkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygxLCBzZXEoMTAsIG1bbGVuZ3RoKG0pXSwgYnkgPSAxMCkpKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gc2VxKGRpZmZbMV0gKyAxMCwgZGlmZltsZW5ndGgoZGlmZildLCBieSA9IDUwKSwgY29sb3IgPSAiZ3JleTMwIiwgbGluZXR5cGUgPSAiZG90dGVkIikgKyAjIGdyaWQgbGluZXMKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBzZXEoMTAsIG1bbGVuZ3RoKG0pXSwgYnkgPSAxMCksIGNvbG9yID0gImdyZXkzMCIsIGxpbmV0eXBlID0gImRvdHRlZCIpICsgIyBncmlkIGxpbmVzCiAgdGhlbWVfYncoKSArCiAgbGFicyh0aXRsZSA9IFRlWCgiJFxcRGVsdGEgciQgZm9yIFxcdGV4dGJme0xvc3N9IiksCiAgICAgICBzdWJ0aXRsZSA9ICJIaWdoZXIgcmF0ZWQgcGxheWVyIGxvc2VzIGFnYWluc3QgYSBsb3dlciByYXRlZCBwbGF5ZXIiLAogICAgICAgeCA9IFRlWCgicl97UDJ9IC0gcl97UDF9IiksCiAgICAgICB5ID0gIk1hcmdpbiBvZiBEZWZlYXQgKG0pIikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoc2l6ZSA9IDEpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwKICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCwgdmp1c3QgPSAtMC41KSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKQogICkKCmRpcmVjdC5sYWJlbChnNiwgbGlzdChjb2xvdXI9J2JsYWNrJywgImZhci5mcm9tLm90aGVycy5ib3JkZXJzIiwgImNhbGMuYm94ZXMiLCAiZW5sYXJnZS5ib3giLCAKICAgICAgaGp1c3QgPSAxLCB2anVzdCA9IDEuMiwgYm94LmNvbG9yID0gTkEsIGZpbGwgPSAidHJhbnNwYXJlbnQiLCAiZHJhdy5yZWN0cyIpKQpgYGAKCioqKgoKPGgxIGlkPSJBcHBlbmRpeF9BIj48L2gxPgojIEFwcGVuZGl4IEEgLSBFZmZlY3Qgb2YgTm8uIG9mIFJvdW5kcyBQbGF5ZWQKClRoZSBiZWxvdyBwbG90IHByb3ZpZGVzIGEgbXVsdGlwbGVyIHZhbHVlICgkbCQpIGZvciBkaWZmZXJlbnQgbGVuZ3RocyBvZiBnYW1lcy4gSWYgeW91IHBsYXkgbG9uZ2VyIG9yIHNob3J0ZXIgZ2FtZXMgeW91IGNhbiBmaW5kIGEgbXVsdGlwbGllciBmb3IgdGhhdCBudW1iZXIgb2Ygcm91bmRzICgkbiQpLCBhbmQgbXVsdGlwbHkgaXQgYnkgdGhlIHZhbHVlIG9mICRcRGVsdGEgciQgZm91bmQgaW4gb25lIG9mIHRoZSBhYm92ZSBwbG90cyB0byBmaW5kIGhvdyB0aGUgcmF0aW5nIGNoYW5nZXMgZm9yIGEgZ2FtZSBvZiB0aGF0IGxlbmd0aC4gRm9yIGV4YW1wbGUsIGlmIHlvdSBwbGF5IGEgZ2FtZSBvZiA2MyByb3VuZHMsIHlvdSBtdWx0aXBseSAkXERlbHRhIHIkIGJ5IDEuNSB0byBmaW5kIGhvdyBtdWNoIHlvdXIgcmF0aW5nIGNoYW5nZXMuIFRoZSBtdWx0aXBsaWVyIGlzIGNhcHBlZCBhdCAkbCA9IDIkLCBzbyB0aGF0IGdhbWVzIG9mIDI1NSByb3VuZHMgb3IgbW9yZSBoYXZlIHRoZSBzYW1lIGVmZmVjdC4gR2FtZXMgb2YgbGVzcyB0aGFuIDI1NSByb3VuZHMgaGF2ZSBhIG11bHRpcGxpZXIgdmFsdWUgYmV0d2VlbiAwIGFuZCAyLiBUaGUgbmF0dXJlIG9mIHRoZSBtdWx0aXBsaWVyIGlzIHN1Y2ggdGhhdCB5b3UgaGF2ZSB0byBwbGF5IHF1aXRlIGEgbG9uZyBnYW1lIHRvIGhhdmUgYSBzaWduaWZpY2FudCBlZmZlY3Qgb24gdGhlIHJhdGluZy4gU2V2ZXJhbCAnbmljZScgb3IgJ2V2ZW4nIHZhbHVlcyBvZiAkbiQgYW5kICRsJCBoYXZlIGJlZW4gaW5kaWNhdGVkIG9uIHRoZSBwbG90LgoKYGBge3IgZWNobz1GQUxTRSwgZmlnLndpZHRoPTEyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIyMgRGF0YQpOIDwtIDA6MzI1CkwgPC0gaWZlbHNlKE4gPCAyNTUsIG11Kihsb2coMSArIE4pKSwgbGFtYmRhKQpkZl9sIDwtIGRhdGEuZnJhbWUoTiwgbCkKbF9ldmVuIDwtIGMoMywgNywgMTUsIDMxLCA1MCwgNjMsIDEwMCwgMTI3LCAyMDAsIDI1NSkgIyBWYWx1ZXMgb2YgbiB0aGF0IHByb3ZpZGVkICduaWNlJyBvciAnZXZlbicgdmFsdWVzIG9mIGwKCiMjIyBQbG90CmdfTCA8LSBnZ3Bsb3QoZGZfbCwgYWVzKE4sIEwpKSArCiAgZ2VvbV9saW5lKCkKCmZvcihsIGluIGxfZXZlbikgewogIGdfTCA8LSBnX0wgKyBnZW9tX3NlZ21lbnQoYWVzX3N0cmluZyh4ID0gbCwgeGVuZCA9IGwsIHkgPSAwLCB5ZW5kID0gbXUqKGxvZygxICsgbCkpKSwgY29sb3IgPSAiY29ybmZsb3dlcmJsdWUiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgICAgICAgICAgICAgIGdlb21fc2VnbWVudChhZXNfc3RyaW5nKHggPSAwLCB4ZW5kID0gbCwgeSA9IG11Kihsb2coMSArIGwpKSwgeWVuZCA9IG11Kihsb2coMSArIGwpKSksIGNvbG9yID0gImNvcm5mbG93ZXJibHVlIiwgbGluZXR5cGUgPSAiZGFzaGVkIikKfQoKZ19MICsKICBsYWJzKHRpdGxlID0gIkhvdyB0aGUgTXVsdGlwbGllciAobCkgdmFyaWVzIHdpdGggTnVtYmVyIG9mIFJvdW5kcyBQbGF5ZWQgKG4pIiwgeCA9ICJOby4gb2YgUm91bmRzIChuKSIsIHkgPSAiTXVsdGlwbGllciAobCkiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwgMTAwLCAyMDAsIGxfZXZlbikpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwLCByb3VuZChtdSoobG9nKDEgKyBsX2V2ZW4pKSwgMikpKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKDAsIE5bbGVuZ3RoKE4pXSksIHlsaW0gPSBjKDAsIDIuMiksIGV4cGFuZCA9IDApICsKICB0aGVtZV9idygpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKHNpemUgPSAwKSwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKHNpemUgPSAwKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCwgaGp1c3QgPSAwLjUpLAogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4KSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCB2anVzdCA9IC0wLjUpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpCiAgKQpgYGAKCioqKgoKPGgxIGlkPSJBcHBlbmRpeF9CIj48L2gxPgojIEFwcGVuZGl4IEIgLSBFeGFtcGxlcwoKVGhlc2UgdHdvIGV4YW1wbGVzIHNob3cgaG93IHRvIGZpbmQgJFxEZWx0YSByJCBpbiB0aGUgY2FzZSBvZiBhIHdpbi4gRm9yIGEgbG9zcywgcHJvY2VlZCBpbiBhIHNpbWlsYXIgbWFubmVyLCBleGNlcHQgdXNlIG9uZSBvZiB0aGUgcGxvdHMgdGl0bGVkICcqKlAxIExvc2VzKionLgoKIyMgRXhhbXBsZSAxICAKClBsYXllciAxIGhhcyBhIHJhdGluZyBvZiAxLDAwMCBwb2ludHMgKCRyX3tQMX0gPSAxLDAwMCQpIHdoaWxlIHBsYXllciAyIGhhcyBhIHJhdGluZyBvZiAxLDEwMCBwb2ludHMgKCRyX3tQMn0gPSAxLDEwMCQpLiBUaGUgZGlmZmVyZW5jZSBpbiByYXRpbmdzIGlzIDEwMCBwb2ludHMgKCRyX3tQMn0gLSByX3tQMX0gPSAxMDAkKS4gUGxheWVyIDEgd2lucyB0aGUgZ2FtZSBieSAxMCBwb2ludHMgKCRtID0gMTAkKS4gT24gYSBwbG90IGZvciAqKlAxIFdpbnMqKiwgZHJhdyBhIGxpbmUgdXAgZnJvbSB0aGUgMTAwIG1hcmsgb24gdGhlIHgtYXhpcywgYW5kIGEgbGluZSBhY3Jvc3MgZnJvbSAxMCBvbiB0aGUgeS1heGlzLiBUaGlzIGlzIHNob3duIGluIHRoZSBvcmFuZ2UgYXJyb3dzIG9uIHRoZSBwbG90IGJlbG93LiBDb252ZW5pZW50bHksIHRoZSBpbnRlcnNlY3Rpb24gb2YgdGhlc2UgbGluZXMgbGFuZHMgcmlnaHQgb24gdGhlICRcRGVsdGEgciQgY29udG91ciBsaW5lIHdob3NlIHZhbHVlIGlzIDE2LiBUaGVyZWZvcmUgcGxheWVyIDEgZ2FpbnMgMTYgcG9pbnRzIGFmdGVyIHRoaXMgZ2FtZS4KCiMjIEV4YW1wbGUgMiAgCgpPZnRlbiB0aGUgbnVtYmVycyBhcmVuJ3Qgc28gbmljZSBhbmQgd2UgaGF2ZSB0byBkbyBzby1jYWxsZWQgaW50ZXJwb2xhdGluZyB0byBmaW5kIG91ciB2YWx1ZSBvZiAkXERlbHRhIHIkLiBUaGlzIGV4YW1wbGUgaWxsdXN0cmF0ZXMgdGhhdCBwcm9jZXNzLiBQbGF5ZXIgMSBoYXMgYSByYXRpbmcgb2YgODAwIHBvaW50cyAoJHJfe1AxfSA9IDgwMCQpIHdoaWxlIHBsYXllciAyIGhhcyBhIHJhdGluZyBvZiAxLDA3NyBwb2ludHMgKCRyX3tQMn0gPSAxLDA3NyQpLiBUaGUgZGlmZmVyZW5jZSBpbiByYXRpbmdzIGlzIDI3NyBwb2ludHMgKCRyX3tQMn0gLSByX3tQMX0gPSAyNzckKS4gUGxheWVyIDEgd2lucyB0aGUgZ2FtZSBieSAyNSBwb2ludHMgKCRtID0gMjUkKS4gVGhlc2UgbnVtYmVycyBhcmVuJ3QgbWFya2VkIG9uIHRoZSBheGVzLCBzbyB3ZSBpbnN0ZWFkIGludGVycG9sYXRlIHRvIGZpbmQgdGhlIHZhbHVlLiBUaGlzIGlzIGVzc2VudGlhbGx5IGd1ZXNzaW5nIHdpdGggb3VyIGV5ZSB3aGVyZSB0aGUgdmFsdWUgYXBwZWFycyBvbiB0aGUgYXhpcy4gRHJhdyBhIGxpbmUgdXAgZnJvbSBhYm91dCBoYWxmd2F5IGJldHdlZW4gdGhlIDI1MCBhbmQgMzAwIG1hcmtzIG9uIHRoZSB4LWF4aXMgKGZvciAkcl97UDJ9IC0gcl97UDF9ID0gMjc3JCksIGFuZCBhIGxpbmUgYWNyb3NzIGZyb20gaGFsZndheSBiZXR3ZWVuIDIwIGFuZCAzMCBvbiB0aGUgeS1heGlzIChmb3IgJG0gPSAyNSQpLiBUaGlzIGlzIHNob3duIGluIHRoZSBwdXJwbGUgYXJyb3dzIG9uIHRoZSBwbG90IGJlbG93LiBVbmZvcnR1bmF0ZWx5LCB0aGUgaW50ZXJzZWN0aW9uIG9mIHRoZXNlIGxpbmVzIGRvZXNuJ3QgbGFuZCByaWdodCBvbiBhICRcRGVsdGEgciQgY29udG91ciBsaW5lLiBJbnN0ZWFkIHdlIG11c3QgaW50ZXJwb2xhdGUgdG8gZmluZCB0aGUgdmFsdWUgb2YgJFxEZWx0YSByJC4gVGhlIGludGVyc2VjdGlvbiBwb2ludCBpcyBhYm91dCBoYWxmd2F5IGJldHdlZW4gdGhlIGNvbnRvdXIgbGluZXMgd2l0aCB2YWx1ZXMgb2YgMjYgYW5kIDI4LiBUaGVyZWZvcmUgd2UgY2FuIGVzdGltYXRlIGEgdmFsdWUgZm9yICRcRGVsdGEgciQgb2YgMjcgaW4gdGhpcyBjYXNlLgoKCmBgYHtyIGVjaG89RkFMU0UsIGZpZy53aWR0aD0xMiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBFeGFtcGxlIDEKZGlmZjEgPSAxMDAKbTEgPSAxMApkZWx0YS5yMSA8LSAoYWxwaGEgKyBiZXRhICogbTEpICogKDEgLSAxIC8gKDEgKyBleHAoZ2FtbWEqKGRpZmYxKSkpKSAqICgxKSAqICgxKSAjIGIqYypwKmwKCiMgRXhhbXBsZSAyCmRpZmYyID0gMjc3Cm0yID0gMjUKZGVsdGEucjIgPC0gKGFscGhhICsgYmV0YSAqIG0yKSAqICgxIC0gMSAvICgxICsgZXhwKGdhbW1hKihkaWZmMikpKSkgKiAoMSkgKiAoMSkgIyBiKmMqcCpsCgojIHNlZSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMTA5NTMwNTAgdGhlIGBkYXRhID0gZGF0YS5mcmFtZSgpIGFyZ3VtZW50IHRvIGBnZW9tX3RleHQoKWAKZzkgPC0gZzcgKwogIGdlb21fc2VnbWVudChhZXMoeCA9IGRpZmYxLCB4ZW5kID0gZGlmZjEsIHkgPSAwLCB5ZW5kID0gbTEpLCBjb2xvciA9ICJkYXJrb3JhbmdlMyIsCiAgICAgICAgICAgICAgIGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgwLjEsICJpbmNoZXMiKSwgdHlwZSA9ICJjbG9zZWQiKSkgKwogIGdlb21fc2VnbWVudChhZXMoeCA9IC00MTAsIHhlbmQgPSBkaWZmMSwgeSA9IG0xLCB5ZW5kID0gbTEpLCBjb2xvciA9ICJkYXJrb3JhbmdlMyIsCiAgICAgICAgICAgICAgIGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgwLjEsICJpbmNoZXMiKSwgdHlwZSA9ICJjbG9zZWQiKSkgKwogIGdlb21fc2VnbWVudChhZXMoeCA9IGRpZmYyLCB4ZW5kID0gZGlmZjIsIHkgPSAwLCB5ZW5kID0gbTIpLCBjb2xvciA9ICJkYXJrc2xhdGVibHVlIiwKICAgICAgICAgICAgICAgYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDAuMSwgImluY2hlcyIpLCB0eXBlID0gImNsb3NlZCIpKSArCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gLTQxMCwgeGVuZCA9IGRpZmYyLCB5ID0gbTIsIHllbmQgPSBtMiksIGNvbG9yID0gImRhcmtzbGF0ZWJsdWUiLAogICAgICAgICAgICAgICBhcnJvdyA9IGFycm93KGxlbmd0aCA9IHVuaXQoMC4xLCAiaW5jaGVzIiksIHR5cGUgPSAiY2xvc2VkIikpICsKICBnZW9tX3RleHQoZGF0YSA9IGRhdGEuZnJhbWUoKSwgYWVzKHggPSAtMTUwLCB5ID0gMjUsIHZqdXN0ID0gMS4xLCBsYWJlbCA9ICJtID0gMjUiKSwgc2l6ZSA9IDYpICsKICBnZW9tX3RleHQoZGF0YSA9IGRhdGEuZnJhbWUoKSwgYWVzKHggPSAtMTUwLCB5ID0gMTAsIHZqdXN0ID0gMS4xLCBsYWJlbCA9ICJtID0gMTAiKSwgc2l6ZSA9IDYpICsKICBnZW9tX3RleHQoZGF0YSA9IGRhdGEuZnJhbWUoKSwgYWVzKHggPSBkaWZmMSwgeSA9IDMsIGhqdXN0ID0gMS4wNSwgbGFiZWwgPSBUZVgoInJfe1AxfSAtIHJfe1AyfSA9IDEwMFxccmlnaHRhcnJvdyIsIG91dHB1dD0nY2hhcmFjdGVyJykpLCBwYXJzZSA9IFRSVUUsIHNpemUgPSA2LCBjb2xvciA9ICJkYXJrb3JhbmdlMyIpICsKICBnZW9tX3RleHQoZGF0YSA9IGRhdGEuZnJhbWUoKSwgYWVzKHggPSBkaWZmMiwgeSA9IDMsIGhqdXN0ID0gMS4wNSwgbGFiZWwgPSBUZVgoInJfe1AxfSAtIHJfe1AyfSA9IDI3N1xccmlnaHRhcnJvdyIsIG91dHB1dD0nY2hhcmFjdGVyJykpLCBwYXJzZSA9IFRSVUUsIHNpemUgPSA2LCBjb2xvciA9ICJkYXJrc2xhdGVibHVlIikgKwogICNnZW9tX3RleHQoYWVzKHggPSBkaWZmMSwgeSA9IG0xLCBoanVzdCA9IDEsIGxhYmVsID0gVGVYKCIkXFxEZWx0YSByID0gMTYkIikpLCBzaXplID0gNikgKwogIGdlb21fdGV4dChkYXRhID0gZGF0YS5mcmFtZSgpLCBhZXMoeCA9IGRpZmYxLCB5ID0gbTEsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLCBsYWJlbCA9ICIxNiIpLCBzaXplID0gNikgKwogIGdlb21fdGV4dChkYXRhID0gZGF0YS5mcmFtZSgpLCBhZXMoeCA9IGRpZmYyLCB5ID0gbTIsIGhqdXN0ID0gLTAuMSwgdmp1c3QgPSAtMC4xLCBsYWJlbCA9ICIyNyIpLCBzaXplID0gNikgKwogIGdlb21fcG9pbnQoZGF0YSA9IGRhdGEuZnJhbWUoKSwgYWVzKHggPSBkaWZmMSwgbTEpLCBjb2xvciA9ICJibGFjayIpICsKICBnZW9tX3BvaW50KGRhdGEgPSBkYXRhLmZyYW1lKCksIGFlcyh4ID0gZGlmZjIsIG0yKSwgY29sb3IgPSAiYmxhY2siKQoKZGlyZWN0LmxhYmVsKGc5LCBsaXN0KGNvbG91cj0nYmxhY2snLCAiZmFyLmZyb20ub3RoZXJzLmJvcmRlcnMiLCAiY2FsYy5ib3hlcyIsICJlbmxhcmdlLmJveCIsIAogICAgICAgICAgICAgICAgICAgIGhqdXN0ID0gMSwgdmp1c3QgPSAxLjUsIGJveC5jb2xvciA9IE5BLCBmaWxsID0gInRyYW5zcGFyZW50IiwgImRyYXcucmVjdHMiKSkKYGBg